package com.bryanbibat.flashcards.spring;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class DeckController {
  
  @Autowired
  DeckService deckService;
  
  @RequestMapping(value = "/decks", method = RequestMethod.GET)
  public String listDecks(ModelMap model) {
    model.addAttribute(deckService.getAll());
    return "decks";
  }

  @RequestMapping(value = "/decks/new", method = RequestMethod.GET)
  public String newDeck(ModelMap model) {
    model.addAttribute(deckService.getAll());
    model.addAttribute(new Deck());
    return "newDeck";
  }
  
  @RequestMapping(value = "/decks/create", method = RequestMethod.POST)
  public String createDeck(@ModelAttribute Deck deck, BindingResult result, ModelMap model) {
    new DeckValidator(deckService, true).validate(deck, result);
    if (result.hasErrors()) {
      model.addAttribute(deckService.getAll());
      return "newDeck";
    }
    deckService.saveDeck(deck);
    return "redirect:/app/decks/" + encodeId(deck.getId());
  }


  @RequestMapping(value = "/decks/{id}", method = RequestMethod.GET)
  public String showDeck(@PathVariable String id,
                               ModelMap model) {
    model.addAttribute(deckService.getAll());
    Deck deck = deckService.getDeck(id);
    if (deck == null) {
      return "redirect:/app/decks";
    }
    model.addAttribute(deck);
    return "showDeck";
  }
  
  @RequestMapping(value = "/decks/{id}/edit", method = RequestMethod.GET)
  public String editDeck(@PathVariable String id,
                               ModelMap model) {
    model.addAttribute(deckService.getAll());
    Deck deck = deckService.getDeck(id);
    if (deck == null) {
      return "redirect:/app/decks";
    } 
    if (deck.getReadonly() != null && deck.getReadonly()) {
      return "redirect:/app/decks/" + encodeId(deck.getId()) + "/show";
    }
    model.addAttribute(deck);
    return "editDeck";
  }
  
  @RequestMapping(value = "/decks/{id}/update", method = RequestMethod.POST)
  public String updateDeck(@PathVariable String id, @ModelAttribute Deck deck, 
      BindingResult result, ModelMap model) {
    deck.setId(id);
    new DeckValidator(deckService).validate(deck, result);
    if (result.hasErrors()) {
      model.addAttribute(deckService.getAll());
      return "editDeck";
    }
    deckService.saveDeck(deck);
    return "redirect:/app/decks/" + encodeId(deck.getId());
  }  
  
  @RequestMapping(value = "/gadget/{id}", method = RequestMethod.GET)
  public String showGadget(@ModelAttribute Settings settings, @PathVariable String id,
                               ModelMap model) {
    model.addAttribute(deckService.getDeck(id));
    model.addAttribute(settings);
    return "gadget";
  }
  
  
  @InitBinder
  public void initLogin(WebDataBinder binder) {
    binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
  }
  
  private String encodeId(String id) {
    String encoded = null;
    try {
      encoded = URLEncoder.encode(id, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return encoded;
  }
  
}
